<template>
  <div>
    <n-card content-style="padding: 5px 5px 5px 5px;">
      <div class="image-container">
        <div class="image-box">
          <div class="image-title">图片</div>
          <div class="tool-bar">
          <n-icon size="20" @click="resetInputImage">
              <Close />
            </n-icon>
          </div>
          <img :src="controlNetForm.image" v-if="controlNetForm.image" alt="输入图片" class="image" @load="resizeImage">
          <n-empty
              description="未上传图片"
              v-if="!controlNetForm.image">
            <template #extra>
              <n-upload
                  :custom-request="customRequest"
              >
                <n-button >上传图片</n-button>
              </n-upload>
            </template>
          </n-empty>
        </div>
        <div class="image-box">
          <div class="image-title">预处理预览</div>
          <img :src="previewImage" v-if="previewImage" alt="结果预览" class="image" @load="resizeImage">
        </div>
      </div>
      <n-form>
        <n-form-item>
          <n-space>
            <n-checkbox v-model:checked="controlNetForm.is_enable">启用</n-checkbox>
            <n-checkbox v-model:checked="controlNetForm.low_vram">低显存模式</n-checkbox>
            <n-checkbox v-model:checked="controlNetForm.pixel_perfect">完美像素模式</n-checkbox>
          </n-space>
        </n-form-item>
        <n-form-item label="控制类型">
          <n-radio-group v-model:value="controlNetForm.preProcessor" @update:value="preProcessChecked">
            <n-space>
              <n-radio v-for="key in Object.keys(controlNetTypeObj)" :key="key" :value="key">
                {{key}}
              </n-radio>
            </n-space>
          </n-radio-group>
        </n-form-item>


        <n-grid x-gap="6" v-if="module_list" >
          <n-gi :span="10">
            <n-form-item label="预处理器" >
              <n-select :options="module_list" v-model:value="controlNetForm.module" clearable>
              </n-select>
            </n-form-item>
          </n-gi>
          <n-gi :span="10">
            <n-form-item label="模型">
              <n-select :options="modelList" v-model:value="controlNetForm.model" clearable>
              </n-select>
            </n-form-item>
          </n-gi>
          <n-gi :span="3">
            <n-form-item>
              <n-button type="primary" @click="controlNetDetect" :loading="controlNetDetectLoading">预处理</n-button>
            </n-form-item>
          </n-gi>
        </n-grid>

        <n-grid x-gap="6" :cols="3">
          <n-gi>
            <n-form-item label="控制权重">
              <n-input-number :min="0" :max="2" :step="0.01" v-model:value="controlNetForm.weight">
              </n-input-number>
            </n-form-item>
          </n-gi>
          <n-gi>
            <n-form-item label="引导接入时机">
              <n-input-number :min="0" :max="1" :step="0.01" v-model:value="controlNetForm.guidance_start">
              </n-input-number>
            </n-form-item>
          </n-gi>

          <n-gi>
            <n-form-item label="引导终止时机">
              <n-input-number :min="0" :max="1" :step="0.01" v-model:value="controlNetForm.guidance_end">
              </n-input-number>
            </n-form-item>
          </n-gi>

          <n-gi>
            <n-form-item label="Preprocessor Resolution">
              <n-input-number :min="64" :max="2048" :step="1" v-model:value="controlNetForm.processor_res">
              </n-input-number>
            </n-form-item>
          </n-gi>
          <n-gi>
            <n-form-item label="Canny Low Threshold">
              <n-input-number :min="1" :max="255" :step="1" v-model:value="controlNetForm.threshold_a">
              </n-input-number>
            </n-form-item>
          </n-gi>

          <n-gi>
            <n-form-item label="Canny High Threshold">
              <n-input-number :min="1" :max="255" :step="1" v-model:value="controlNetForm.threshold_b">
              </n-input-number>
            </n-form-item>
          </n-gi>
        </n-grid>

        <n-row>
          <n-col :span="12">
             <n-form-item label="控制模式">
                <n-radio-group v-model:value="controlNetForm.control_mode">
                  <n-radio :value=0>均衡</n-radio>
                  <n-radio :value=1>更偏向提示词</n-radio>
                  <n-radio :value=2>更偏向ControlNet</n-radio>
                </n-radio-group>
             </n-form-item>
          </n-col>

          <n-col :span="12">
            <n-form-item label="缩放模式" >
              <n-radio-group v-model:value="controlNetForm.resize_mode">
                <n-radio :value=0>仅调整大小</n-radio>
                <n-radio :value=1>裁剪后缩放</n-radio>
                <n-radio :value=2>缩放后填充空白</n-radio>
              </n-radio-group>
            </n-form-item>
          </n-col>
        </n-row>
      </n-form>

    </n-card>
  </div>
</template>

<script setup lang="ts">
import {computed, nextTick, onMounted, reactive, ref} from 'vue';
  import {UploadCustomRequestOptions, useMessage} from 'naive-ui';
  // @ts-ignore
  import fileFunction from "@/libs/globalFunction/file"
  import { GameControllerOutline, GameController ,Close } from '@vicons/ionicons5'
  import {sdControllerApi} from '@/api/sd/sdController.api'
  const previewImage = ref('')
  const maxWidth = ref(230)
  const maxHeight = ref(230)
  const controlNetTypeObj = ref({})
  const modelList = ref([])
  const module_list = ref([])
  const controlNetDetectLoading = ref(false)

  const props = defineProps({
    sdResourceId: {
      type: String,
      required: true
    }
  })

  onMounted(() => {
    getControlNetType(props.sdResourceId)
  })
  const getControlNetType = (sdResourceId:string) => {
    sdControllerApi.getControlNetType(sdResourceId).then(res => {
      if(res.code === 200){
        controlNetTypeObj.value = res.data.control_types
        nextTick(() => {
          preProcessChecked(Object.keys(controlNetTypeObj.value)[0])
        })
      }
    })
  }

  const controlNetForm:SD.SDControlNet = reactive({
    image: '',
    mask: '',
    module: 'None',
    model: 'None',
    weight: 1.0 ,
    resize_mode: "Scale to Fit (Inner Fit)",
    low_vram : false,
    processor_res: 512,
    threshold_a : 64,
    threshold_b : 64,
    guidance_start: 0,
    guidance_end: 1,
    control_mode: "Balanced",
    pixel_perfect : false,
    preProcessor: 'All',
    enabled : false
  })

  const customRequest = (uploadOption:UploadCustomRequestOptions) => {
    const reader = new FileReader();
    //@ts-ignore
    reader.readAsDataURL(uploadOption.file.file);
    reader.onloadend = () => {
      let image = new Image()
      image.src = reader.result
      //@ts-ignore
      controlNetForm.input_image = reader.result
      image.onload = function () {
        // sdImg2ImgPrompt.width = image.width
        // sdImg2ImgPrompt.height = image.height
        // // 计算图片宽高比例
        // let imgRatio = image.width / image.height
        // if (image.width > 600
        //     || image.height > 600) {
        //   // 计算缩放后的宽高
        //   if (imgRatio > 1) {
        //     canvasWidth.value = 600
        //     canvasHeight.value = image.height / (image.width / 600)
        //   } else {
        //     // 图片比较宽
        //     canvasWidth.value = image.width / (image.height / 600)
        //     canvasHeight.value = 600
        //   }
        // }else {
        //   canvasWidth.value = image.width
        //   canvasHeight.value = image.height
        // }
        // console.log(canvasWidth.value, canvasHeight.value)
      }
    };
  }

  const preProcessChecked = (key:string) => {
    module_list.value = []
    modelList.value = []
    controlNetTypeObj.value[key]['module_list'].forEach((item:any) => {
      module_list.value.push({
          label: item,
          value: item
        })
    })
    controlNetTypeObj.value[key]['model_list'].forEach((item:any) => {
      modelList.value.push({
          label: item,
          value: item
        })
    })
  }

  const controlNetDetect = () =>{
    controlNetDetectLoading.value = true
    const controlNetInputImages = []
    controlNetInputImages.push(controlNetForm.image)
    const param ={
      resourceId: props.sdResourceId,
      controlNetModule:  controlNetForm.module,
      controlNetInputImages:  controlNetInputImages,
      controlNetThresholdLow: 54,
      controlNetProcessorRes: 512,
      controlNetThresholdHigh: 54
    }
    sdControllerApi.controlNetDetect(param).then(res => {
      controlNetDetectLoading.value = false
      if(res.code === 200){
        if(res.data.info == 'Success'){
          decodeBase64ToImage(res.data.images[0])
        }
      }
    })
  }
  const resetInputImage = () =>{
    controlNetForm.image = ''
  }

  const resizeImage = (e: any) => {
    const image = e.target;
    if (image.width > maxWidth.value || image.height > maxHeight.value) {
      const widthRatio = maxWidth.value / image.width;
      const heightRatio = maxHeight.value / image.height;
      const scale = Math.min(widthRatio, heightRatio);
      image.width = image.width * scale;
      image.height = image.height * scale;
    }
  }

  const decodeBase64ToImage = (base64:string) => {
    previewImage.value = "data:image/png;base64," + base64
  }

  const getControlNetInfo = () => {
    return controlNetForm
  }
  defineExpose({
    getControlNetInfo
  })
</script>
<style>
.image-container {
  display: flex;
  height: 250px;
}

.image-box {
  flex: 1;
  height: 230px;
  padding: 10px;
  text-align: center;
  border: 1px solid #ccc;
  position: relative;
}

.image {
  max-width: 100%;
  max-height: 100%;
  height: auto;
}

.tool-bar {
  position: absolute;
  top: 0;
  right: 0;
  padding: 5px;
}

.image-title {
  position: absolute;
  top: 10px; /* 调整标题与顶部的距离 */
  left: 10px; /* 调整标题与左侧的距离 */
  font-size: 18px; /* 调整标题的字体大小 */
}
</style>
